package independence.reflection
{
	import independence.core.IndyObject;
	/**
	 * The Constant class represents a member declared in a class with the
	 * <code>const</code> keyword, a read-only member that cannot be changed.
	 * This class defines methods specifically for working with constants.
	 * 
	 * @author	TK, TK Assembled for Independence Glory.
	 */
	public class Constant extends IndyObject implements IReadableMember
	{
		/**
		 * @protected The clazz object which defines this constant.
		 */
		protected var clazz:Class;
		/**
		 * @protected The String name of the constant property.
		 */
		protected var constName:String;
		/**
		 * @protected The return type of this constant.
		 */
		protected var type:Class;
		/**
		 * @protected Whether the constant is static or not.
		 */
		protected var statik:Boolean;
		/**
		 * Constructs a new Constant object.
		 * @param	clazz		The declaring class of this constant.
		 * @param	constName	The String name of the constant property.
		 * @param	statik		A boolean value indicating whether a constant is static or not.
		 */
		public function Constant(clazz:Class, constName:String, type:Class, statik:Boolean = false)
		{
			this.clazz = clazz;
			this.constName = constName;
			this.statik = statik
			this.type = type;
		}
		/**
		 * Returns the class which declares this constant.
		 * @return	The class which declares this constant as a member.
		 */
		public function getDeclaringClass():Class
		{
			return clazz;
		}
		/**
		 * Returns the constant's return type.
		 * @return	The class return type of this constant.
		 */
		public function getType():Class
		{
			return type;
		}
		/**
		 * Returns the name of the constant property.
		 * @return	The String name of the constant property.
		 */
		public function getName():String
		{
			return constName;
		}
		/**
		 * Returns whether the constant is static or not.
		 * @return	True if the constant is static, false otherwise.
		 */
		public function isStatic():Boolean
		{
			return statik;
		}
		/**
		 * Gets the value of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The value of this constant in the <code>target</code> object.
		 */
		public function getValue(target:Object):Object 
		{
			return statik ? clazz[constName] : target[constName];
		}
		/**
		 * Get the Array value of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The Array value of this constant in the <code>target</code> object.
		 */
		public function getArray(target:Object):Array 
		{
			return this.getValue(target) as Array;
		}
		/**
		 * Gets the boolean value of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The boolean value of this constant in the <code>target</code> object.
		 */
		public function getBoolean(target:Object):Boolean
		{
			return Boolean(getValue(target));
		}
		/**
		 * Gets the integer value (int) of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The integer value of this constant in the <code>target</code> object.
		 */
		public function getInteger(target:Object):int
		{
			return int(getValue(target));
		}
		/**
		 * @inheritDoc
		 */
		public function getNumber(target:Object):Number
		{
			return Number(getValue(target));
		}
		/**
		 * Gets the string value of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The string value of this constant in the <code>target</code> object.
		 */
		public function getString(target:Object):String
		{
			return String(getValue(target));
		}
		/**
		 * Gets the unsigned integer (uint) value of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The unsigned integer value of this constant in the <code>target</code> object.
		 */
		public function getUnsignedInt(target:Object):uint
		{
			return uint(getValue(target));
		}
		/**
		 * Gets the XML value of this constant in the <code>target</code> object.
		 * @param	target	The target object of which to get the value of this constant.
		 * @return	The XML value of this constant in the <code>target</code> object.
		 */
		public function getXML(target:Object):XML
		{
			return XML(getValue(target));
		}
		/**
		 * Returns a String representation of this <code>Constant</code> object.
		 * @return	A String representation of this <code>Constant</code>.
		 */
		public function toString():String
		{
			return "[Constant " + this.constName + "]";
		}
	}
}